package com.example.ssyinitlearn.userDetailsServiceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.ssyinitlearn.entity.RoleEntity;
import com.example.ssyinitlearn.entity.UserEntity;
import com.example.ssyinitlearn.entity.UserRoleRelationEntity;
import com.example.ssyinitlearn.service.RoleService;
import com.example.ssyinitlearn.service.UserRoleRelationService;
import com.example.ssyinitlearn.service.UserService;
import com.example.ssyinitlearn.userDetailsImpl.UserEntityImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserEntityServiceImpl implements UserDetailsService {

    // 引入数据库查询的服务
    @Autowired
    UserService userService;
    @Autowired
    RoleService roleService;
    @Autowired
    UserRoleRelationService userRoleRelationService;

    /**
     * 只需要实现 UserDetailsService唯一的方法，即返回一个 UserDetails的实现类(也就是用户对象)
     * @param username
     * @return
     * @throws UsernameNotFoundException
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // 从数据库中查出 username对应的 UserEntity
        // 注意，username不一定就是用户名，之前就说过。必须要看此时的这个 UserDetailsService将被用在哪一个环境下，才能确定这里的 username是啥
        UserEntity dataBaseUser = userService.getOne(new QueryWrapper<UserEntity>().eq("username", username));
        if(dataBaseUser == null){
            throw new UsernameNotFoundException("UserEntityServiceImpl 用户不存在:" + username);
        }

        // 若用户存在，开始构建 UserDetails对象.
        UserEntityImpl userEntityImpl = new UserEntityImpl();
        // 将原始数据库对象的属性值复制过来
        BeanUtils.copyProperties(dataBaseUser, userEntityImpl);
        // 查出角色列表。当然直接自己写一个mapper方法在数据库中JOIN查询也是可以的
        List<RoleEntity> roleEntityList = userRoleRelationService.list(new QueryWrapper<UserRoleRelationEntity>().eq("uid", dataBaseUser.getId())).stream().map(
                userRoleRelationEntity -> {
                    return roleService.getById(userRoleRelationEntity.getRid());
                }
        ).collect(Collectors.toList());

        userEntityImpl.setRoleEntityList(roleEntityList);

        return userEntityImpl;
    }
}
